/*
 * Range.hpp
 *
 *  Created on: 17-11-2010
 *      Author: Przemek
 */

#pragma once

#include "pch.hpp"

/*
 * Template for an object representing a range of numbers (most likely) - [min,max]
 */
template<typename T>
class Range
{
	private:
		T minimum;
		T maximum;

	public:
		Range(const T& minimum, const T& maximum);
		Range(const Range<T>& other);

		Range& operator=(const Range<T>& other);
		const T& getMinimum() const;
		const T& getMaximum() const;
		T getAverage() const;
		T getExtent() const;
		void setMinimum(const T& minimum);
		void setMaximum(const T& maximum);

		bool isAfterMaximum(const T& value) const;
		bool isBeforeMinimum(const T& value) const;

	private:
		void assureMinimumSmallerThanMaximum();
};

template<typename T>
Range<T>::Range(const T& minimum, const T& maximum) :
	minimum(minimum), maximum(maximum)
{
	assureMinimumSmallerThanMaximum();
}

template<typename T>
Range<T>::Range(const Range<T>& other) :
	minimum(other.minimum), maximum(other.maximum)
{
}

template<typename T>
Range<T>& Range<T>::operator=(const Range<T>& other)
{
	if(this != &other)
	{
		minimum = other.minimum;
		maximum = other.maximum;
	}

	return *this;
}

template<typename T>
const T& Range<T>::getMinimum() const
{
	return minimum;
}

template<typename T>
const T& Range<T>::getMaximum() const
{
	return maximum;
}

template<typename T>
T Range<T>::getAverage() const
{
	return (minimum + maximum) / 2;
}

template<typename T>
T Range<T>::getExtent() const
{
	return (maximum - minimum);
}

template<typename T>
void Range<T>::setMinimum(const T& minimum)
{
	this->minimum = minimum;
	assureMinimumSmallerThanMaximum();
}

template<typename T>
void Range<T>::setMaximum(const T& maximum)
{
	this->maximum = maximum;
	assureMinimumSmallerThanMaximum();
}

template<typename T>
bool Range<T>::isAfterMaximum(const T& value) const
{
	return (value > maximum);
}

template<typename T>
bool Range<T>::isBeforeMinimum(const T& value) const
{
	return (value < minimum);
}

template<typename T>
void Range<T>::assureMinimumSmallerThanMaximum()
{
	if(minimum > maximum)
	{
		std::swap(minimum, maximum);
	}
}
